package com.yikome.order.schedule;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.google.common.collect.ImmutableMap;
import com.yikome.blacklist.entity.BlackList;
import com.yikome.blacklist.request.BlackListSearchRequest;
import com.yikome.blacklist.service.BlackListService;
import com.yikome.order.entity.Order;
import com.yikome.order.entity.OrderAddress;
import com.yikome.order.enums.OrderStatus;
import com.yikome.order.enums.Payment;
import com.yikome.order.mq.request.OrderToAdminProductRequest;
import com.yikome.order.mq.request.OrderToAdminRequest;
import com.yikome.order.repository.OrderAddressRepository;
import com.yikome.order.repository.OrderRepository;
import com.yikome.utils.JSONUtils;

import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;

@Component
public class OrderSchedule {

	@Value("${admin.remoteurl}")
	private String adminUrl ;
	
	@Autowired
	private OrderRepository orderRepository ; 
	
	@Autowired
	private OrderAddressRepository orderAddressRepository; 
	
	@Autowired
	private BlackListService blackListService; 
	
	@Autowired
	private NamedParameterJdbcTemplate jdbcTemplate ;
	
	
	@Scheduled(cron ="0 0/1 * * * ?")
    public void asyncOrderToAdmin() {

		String contentSQL = "SELECT o_order.code FROM o_order WHERE o_order.need_async = 1 AND o_order.is_async = 0" ;
		List<String> orderCodes = jdbcTemplate.queryForList(contentSQL, MapUtil.newHashMap(), String.class);
		
		for (String orderCode : orderCodes) {
		
			OrderToAdminRequest orderToAdminRequest = createOrderToAdminRequest(orderCode);
			
			if(orderToAdminRequest != null && orderToAdminRequest.getOrderToAdminProductRequests() != null && !orderToAdminRequest.getOrderToAdminProductRequests().isEmpty()) {
				
				orderToAdminRequest.setIsBlackList(Boolean.FALSE);
				
				Order order = orderRepository.findOrder(orderCode);
				if(order.getPayment() == Payment.PAYMENT_COD.getCode()) {
					OrderAddress orderAddress = orderAddressRepository.findOrderAddress(orderCode);
					BlackListSearchRequest blackListSearchRequest = new BlackListSearchRequest();
					blackListSearchRequest.setTel(orderAddress.getTel());
					Page<BlackList> blackLists = blackListService.findBlackList(blackListSearchRequest, PageRequest.of(0, 100));
					
					if(!blackLists.isEmpty()) {
						orderToAdminRequest.setIsBlackList(Boolean.TRUE);
					}
				}
				
				HttpResponse execute = HttpRequest.put(adminUrl + "/admin/order/api/create")
					.body(JSONUtils.toJsonString(orderToAdminRequest))
					.execute();
				
				if(execute.isOk()) {
					order.setIsAsync(Boolean.TRUE);
					order.setStatus(OrderStatus.ORDER_STOCK.getStatus());
					orderRepository.save(order);
				}
			}
		}
    }
	
    private OrderToAdminRequest createOrderToAdminRequest(String orderCode) {
    	
    	String orderContentSQL ="SELECT \n" + 
				    			"	o_order.`code`, o_order.payment, o_order.price, o_order.freight, o_order.remark, o_order.currency, o_order_ext.shop_id, o_order_ext.affiliate,  \n" + 
				    			"	o_order_address.consignee, o_order_address.tel, o_order_address.contry, o_order_address.province, o_order_address.city, o_order_address.district, o_order_address.details, o_order_address.zip_code, o_order_address.email, s_shop.storehouse_id \n" + 
				    			"FROM o_order \n" + 
				    			"	LEFT JOIN o_order_ext ON (o_order.`code` = o_order_ext.order_code) \n" + 
				    			"	LEFT JOIN o_order_address ON (o_order.`code` = o_order_address.order_code) \n" + 
				    			"	LEFT JOIN s_shop ON (o_order_ext.shop_id = s_shop.id) \n" + 
				    			"WHERE o_order.`code` = :orderCode \n" ;
    	OrderToAdminRequest orderToAdminRequest = jdbcTemplate.queryForObject(orderContentSQL, ImmutableMap.of("orderCode", orderCode), new BeanPropertyRowMapper<>(OrderToAdminRequest.class));
    	
    	if(orderToAdminRequest == null) return null ;
    	
    	String orderProductSQL ="SELECT  \n" + 
				    			"	o_order_product.product_id, o_order_product.product_title, o_order_product.product_sku_id, o_order_product.product_sku_barcode, o_order_product.product_sku_name, o_order_product.product_price, o_order_product.product_image_url, o_order_product.quantity, \n" + 
				    			"	p_product_ext.source_url, p_product_ext.source_number, p_product_ext.source_id, p_product_ext.source_title, p_product_ext.supplier_id, p_product_sku.purchase_price reference_purchase_price, s_supplier.shop_name supplier_name \n" + 
				    			"FROM o_order_product \n" + 
				    			"	LEFT JOIN p_product_ext ON (o_order_product.product_id = p_product_ext.product_id) \n" + 
				    			"	LEFT JOIN p_product_sku ON (o_order_product.product_sku_id = p_product_sku.id) \n" + 
				    			"	LEFT JOIN s_supplier ON (p_product_ext.supplier_id = s_supplier.id) \n" + 
				    			"WHERE o_order_product.order_code = :orderCode" ; 
    	List<OrderToAdminProductRequest> orderToAdminProductRequests = jdbcTemplate.query(orderProductSQL, ImmutableMap.of("orderCode", orderCode), new BeanPropertyRowMapper<>(OrderToAdminProductRequest.class));
    	
    	orderToAdminRequest.setOrderToAdminProductRequests(orderToAdminProductRequests);
    	return  orderToAdminRequest;
    }
}
